{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "d006b2ea-9dfe-49c7-88a9-a5a0775185fd",
   "metadata": {},
   "source": [
    "# Additional End of week Exercise - week 2\n",
    "\n",
    "Now use everything you've learned from Week 2 to build a full prototype for the technical question/answerer you built in Week 1 Exercise.\n",
    "\n",
    "This should include a Gradio UI, streaming, use of the system prompt to add expertise, and the ability to switch between models. Bonus points if you can demonstrate use of a tool!\n",
    "\n",
    "If you feel bold, see if you can add audio input so you can talk to it, and have it respond with audio. ChatGPT or Claude can help you, or email me if you have questions.\n",
    "\n",
    "I will publish a full solution here soon - unless someone beats me to it...\n",
    "\n",
    "There are so many commercial applications for this, from a language tutor, to a company onboarding solution, to a companion AI to a course (like this one!) I can't wait to see your results."
   ]
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-06T16:52:12.637325Z",
     "start_time": "2025-10-06T16:52:10.174609Z"
    }
   },
   "cell_type": "code",
   "source": [
    "from openai import OpenAI\n",
    "from api_key_loader import ApiKeyLoader\n",
    "import gradio as gr"
   ],
   "id": "40fad776c1390c95",
   "outputs": [],
   "execution_count": 1
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-06T16:52:14.602846Z",
     "start_time": "2025-10-06T16:52:14.599016Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# Initialization\n",
    "keys = ApiKeyLoader()"
   ],
   "id": "df481efd444c3042",
   "outputs": [],
   "execution_count": 2
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-06T16:52:16.325113Z",
     "start_time": "2025-10-06T16:52:16.317253Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# Create LLM client\n",
    "MODEL = \"gpt-4o-mini\"\n",
    "openai = OpenAI()"
   ],
   "id": "50c88632f5e3e8ca",
   "outputs": [],
   "execution_count": 3
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-06T16:52:18.224200Z",
     "start_time": "2025-10-06T16:52:18.198959Z"
    }
   },
   "cell_type": "code",
   "source": "from tool_box import ToolBox",
   "id": "5dde6f905c143779",
   "outputs": [],
   "execution_count": 4
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-06T16:52:19.913686Z",
     "start_time": "2025-10-06T16:52:19.906576Z"
    }
   },
   "cell_type": "code",
   "source": "tool_box = ToolBox(keys)",
   "id": "f999cfc5d533bf4e",
   "outputs": [],
   "execution_count": 5
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-06T16:52:21.515122Z",
     "start_time": "2025-10-06T16:52:21.513463Z"
    }
   },
   "cell_type": "code",
   "source": [
    "system_message = \"You are a helpful assistant for an Travel Agency called TravelAI. \"\n",
    "system_message += \"Give short, courteous answers, no more than 1 sentence. \"\n",
    "system_message += \"Always be accurate. If you don't know the answer, say so.\""
   ],
   "id": "1891e095dc08da95",
   "outputs": [],
   "execution_count": 6
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-06T16:52:26.569153Z",
     "start_time": "2025-10-06T16:52:26.566763Z"
    }
   },
   "cell_type": "code",
   "source": [
    "def chat(history):\n",
    "    messages = [{\"role\": \"system\", \"content\": system_message}] + history\n",
    "    response = openai.chat.completions.create(model=MODEL, messages=messages, tools=tool_box.tools)\n",
    "    image = None\n",
    "\n",
    "    if response.choices[0].finish_reason==\"tool_calls\":\n",
    "        message = response.choices[0].message\n",
    "        tools_response, image = tool_box.apply(message)\n",
    "        messages.append(message)\n",
    "        messages.extend(tools_response)\n",
    "        response = openai.chat.completions.create(model=MODEL, messages=messages)\n",
    "\n",
    "    reply = response.choices[0].message.content\n",
    "    history += [{\"role\":\"assistant\", \"content\":reply}]\n",
    "\n",
    "    return history, image"
   ],
   "id": "b74e96dbf19dceef",
   "outputs": [],
   "execution_count": 7
  },
  {
   "metadata": {},
   "cell_type": "code",
   "source": "resp, image = chat([{\"role\": \"user\", \"content\": \"Show me Milan Airports on the map\"}])",
   "id": "8c4a6f62ed5079f7",
   "outputs": [],
   "execution_count": null
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-06T16:52:59.264912Z",
     "start_time": "2025-10-06T16:52:58.789327Z"
    }
   },
   "cell_type": "code",
   "source": [
    "with gr.Blocks() as ui:\n",
    "    with gr.Row():\n",
    "        chatbot = gr.Chatbot(height=500, type=\"messages\")\n",
    "        image_output = gr.Image(height=500)\n",
    "    with gr.Row():\n",
    "        entry = gr.Textbox(label=\"Chat with our AI Assistant:\")\n",
    "    with gr.Row():\n",
    "        clear = gr.Button(\"Clear\")\n",
    "\n",
    "    def do_entry(message, history):\n",
    "        history += [{\"role\":\"user\", \"content\":message}]\n",
    "        return \"\", history\n",
    "\n",
    "    entry.submit(do_entry, inputs=[entry, chatbot], outputs=[entry, chatbot]).then(\n",
    "        chat, inputs=chatbot, outputs=[chatbot, image_output]\n",
    "    )\n",
    "    clear.click(lambda: None, inputs=None, outputs=chatbot, queue=False)\n",
    "\n",
    "ui.launch(inbrowser=True)"
   ],
   "id": "71809ab63b2973b0",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "* Running on local URL:  http://127.0.0.1:7860\n",
      "* To create a public link, set `share=True` in `launch()`.\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ],
      "text/html": [
       "<div><iframe src=\"http://127.0.0.1:7860/\" width=\"100%\" height=\"500\" allow=\"autoplay; camera; microphone; clipboard-read; clipboard-write;\" frameborder=\"0\" allowfullscreen></iframe></div>"
      ]
     },
     "metadata": {},
     "output_type": "display_data",
     "jetTransient": {
      "display_id": null
     }
    },
    {
     "data": {
      "text/plain": []
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 9
  },
  {
   "metadata": {},
   "cell_type": "code",
   "source": [
    "from travel_api import TravelAPI\n",
    "trave_agent = TravelAPI(keys.get(\"client_id\"), keys.get(\"client_secret\"))\n",
    "airports = trave_agent.get_airport('Milan')\n",
    "print(airports)"
   ],
   "id": "3e63c59c69cbdae9",
   "outputs": [],
   "execution_count": null
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-06T16:52:55.269319Z",
     "start_time": "2025-10-06T16:52:34.020932Z"
    }
   },
   "cell_type": "code",
   "source": "resp, image = chat([{\"role\": \"user\", \"content\": \"Give me a boarding pass from MXP to LHR for 1 Nov 2025 for Sergei Sevriugin\"}])",
   "id": "caa12b84a1863bc1",
   "outputs": [],
   "execution_count": 8
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.13"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
